package com.livegoods.service;

import com.livegoods.commons.pojo.LivegoodsResult;
import com.livegoods.pojo.HouseES;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Service
public class SearchServiceImpl implements SearchService{

    @Autowired
    private ElasticsearchRestTemplate restTemplate;


    @Value("${livegoods.fastdfs.nginx}")
    private String fastdfsNginx;

    @Override
    public LivegoodsResult searchHouseData(String city, String keyword, Integer page,Integer size) {


        MatchQueryBuilder titleMatchQueryBuilder = QueryBuilders.matchQuery("title", keyword);

        MatchQueryBuilder cityMatchmatchQueryBuilder = QueryBuilders.matchQuery("city", city);

        List<QueryBuilder> conditions = Arrays.asList(titleMatchQueryBuilder,cityMatchmatchQueryBuilder);

        //多条件 must(and)关系
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must().addAll(conditions);



        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();

        searchQueryBuilder.withQuery(boolQueryBuilder);
        searchQueryBuilder.withPageable(PageRequest.of(page,size));


        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        highlightBuilder.numOfFragments(5);
        highlightBuilder.fragmentSize(20);


        searchQueryBuilder.withHighlightBuilder(highlightBuilder);


        NativeSearchQuery searchQuery = searchQueryBuilder.build();

        //执行聚合查询
        AggregatedPage<HouseES> houseESAggregatedPage = restTemplate.queryForPage(searchQuery, HouseES.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {

                //获取搜索数据
                SearchHit[] searchHits = response.getHits().getHits();

                List<HouseES> houseESList = new ArrayList<>();
                for (SearchHit searchHit : searchHits) {

                    HouseES houseES = new HouseES();
                    Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();

                    houseES.setId(searchHit.getId());
                    houseES.setHouseType(sourceAsMap.get("houseType").toString());
                    houseES.setPrice(sourceAsMap.get("price").toString());
                    houseES.setRentType(sourceAsMap.get("rentType").toString());
                    houseES.setImg(fastdfsNginx+sourceAsMap.get("img").toString());
                    houseES.setCity(sourceAsMap.get("city").toString());


                    //获取高亮数据
                    Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                    HighlightField highlightField = highlightFields.get("title");
                    Text titleText = highlightField.getFragments()[0];

                    String title = titleText.toString();

                    houseES.setTitle(title);


                    houseESList.add(houseES);
                }

                //获取搜索总数
                long totalHits = response.getHits().totalHits;


                return new AggregatedPageImpl(houseESList,pageable,totalHits);
            }

            @Override
            public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
                return null;
            }
        });


        List<HouseES> houseESList = houseESAggregatedPage.getContent();


        //获取总页数
        int totalPages = houseESAggregatedPage.getTotalPages();

        LivegoodsResult result = LivegoodsResult.ok(houseESList);

        //如果前端页码数等于总页数，说明用用户已经翻到最后一页， hasMore设置false
        if(page+1 < totalPages){
            result.setHasMore(true);
        }else {
            result.setHasMore(false);
        }

        return result;
    }
}
